import { Injectable } from '@nestjs/common';
import { InjectDataSource, InjectRepository } from '@nestjs/typeorm';
import { PaginationDto } from 'src/common/dto/pagination.dto';
import { ToolsService } from 'src/utils/tools.service';
import { DataSource, Repository } from 'typeorm';
import { UsersEntity } from '../user/entities/user.entity';
import { CreateDrawDto } from './dto/create-draw.dto';
import { UpdateDrawDto } from './dto/update-draw.dto';
import { DrawEntity } from './entities/draw.entity';
import { v4 as uuidv4 } from 'uuid';
import * as moment from 'moment';

@Injectable()
export class DrawService {
  @InjectRepository(DrawEntity)
  private readonly DrawRepository: Repository<DrawEntity>;

  @InjectDataSource()
  private readonly dataSource: DataSource;

  async create(createDrawDto: CreateDrawDto, userid: string) {
    const queryRunner = this.dataSource.createQueryRunner();
    try {
      const manager = await queryRunner.manager; //使用事务
      const user = await manager
        .getRepository(UsersEntity)
        .createQueryBuilder('user')
        .where('user.id = :id', {
          id: userid,
        })
        .getOne();
      if (!user) {
        throw new Error('用户不存在');
      }
      const draw = new DrawEntity();
      draw.title = createDrawDto.title;
      draw.content = createDrawDto.content;
      draw.user = user;
      await manager.save(draw);
      return draw;
    } catch (error) {
      ToolsService.fail(error);
    } finally {
      await queryRunner.release(); //释放连接
    }
  }

  async createUseNativeSql(createTagDto: CreateDrawDto) {
    const queryRunner = this.dataSource.createQueryRunner();
    await queryRunner.connect(); //使用我们的新queryRunner建立真正的数据库连
    await queryRunner.startTransaction();
    try {
      let id = uuidv4();
      let created_at = moment().format('YYYY-MM-DD HH:mm:ss');
      let query = `INSERT INTO draw (id,content,created_at) VALUES ('${id}' ,'${createTagDto.content}','${created_at}')`;
      console.log('query', query);
      // 执行原生SQL
      await queryRunner.query(query);
      // 提交事务
      await queryRunner.commitTransaction();
      return true;
    } catch (error) {
      // 回滚事务
      await queryRunner.rollbackTransaction();
      ToolsService.fail(error);
    } finally {
      // 关闭查询运行器
      await queryRunner.release();
    }
  }

  async findAll(title: string, pagination: PaginationDto, userId: string) {
    try {
      const $DrawRepository = await this.DrawRepository.createQueryBuilder(
        'draw',
      );
      $DrawRepository
        .where('draw.title LIKE :param')
        .setParameters({
          param: '%' + title + '%',
        })
        .skip(pagination.currentPage * pagination.pageSize)
        .take(pagination.pageSize)
        .leftJoin('draw.user', 'user')
        .andWhere('user.id = :id', { id: userId })
        .select([
          'draw.id',
          'draw.title',
          'draw.content',
          'draw.created_at',
          'draw.updated_at',
        ])
        .orderBy('draw.created_at', 'DESC'); //DESC ASC
      return $DrawRepository.getManyAndCount();
    } catch (error) {
      ToolsService.fail(error);
    }
  }

  async findOne(id: number) {
    const queryRunner = this.dataSource.createQueryRunner();
    try {
      const manager = await queryRunner.manager; //使用事务
      const draw = await manager
        .getRepository(DrawEntity)
        .createQueryBuilder('draw')
        .where({
          id,
        })
        // .select()
        .getOne();
      return draw;
    } catch (error) {
      ToolsService.fail(error);
    } finally {
      // 关闭查询运行器
      await queryRunner.release();
    }
  }

  async update(id: string, updateDrawDto: UpdateDrawDto) {
    const queryRunner = this.dataSource.createQueryRunner();
    try {
      const manager = await queryRunner.manager; //使用事务
      const draw = new DrawEntity();
      draw.id = id;
      draw.content = updateDrawDto.content;
      draw.title = updateDrawDto.title;
      await manager.save(draw);
      return draw;
    } catch (error) {
      ToolsService.fail(error);
    } finally {
      // 关闭查询运行器
      await queryRunner.release();
    }
  }

  async remove(id: string) {
    try {
      await this.DrawRepository.createQueryBuilder()
        .delete()
        .from(DrawEntity)
        .where('id = :id', { id: id })
        .execute();
    } catch (error) {
      ToolsService.fail(error);
    }
  }
}
